# -*- coding: utf-8 -*-


import ctypes
import importlib
import platform

from base.engine import TradeEngine, QuoteEngine
from base.event_type import *
from ui.dwIndicator import Ui_dwIndicator
# from uiMainWindow import *
from ui.dwTab import Ui_twMain
from ui.uiBasicWidget import *


class UiIndicator(QtWidgets.QDockWidget, Ui_dwIndicator):

    def __init__(self):
        super(UiIndicator, self).__init__()
        self.setupUi(self)


class MainTabUI(QtWidgets.QTabWidget, Ui_twMain):
    signalTick = QtCore.pyqtSignal(type(Event()))

    def __init__(self):
        super(MainTabUI, self).__init__()
        # 调用上级界面初始化过程
        self.setupUi(self)
        # 设置行情引擎和行情事件引擎
        self.quoteEngine = QuoteEngine(shouldSaveData=False)
        self.quoteEventEngine = self.quoteEngine.eventEngine
        # 设置交易引擎和交易事件引擎
        self.mainEngine = TradeEngine(self.quoteEngine)
        self.eventEngine = self.mainEngine.eventEngine

        self.setEventType()

        # 保存行情数据用
        self.tickDict = {}  # 字典，key是字段对应的数据，value是保存相关单元格的字典
        self.tickKey = 'symbol'
        # 保存表头标签用
        # HeaderDic是有序字典，key是英文名，value是对应的配置字典
        self.HeaderList = []  # 对应self.***HeaderDict.keys()
        self.tickHeaderDic = OrderedDict()
        self.tickHeaderList = []
        self.tradeHeaderDic = OrderedDict()
        self.tradeHeaderList = []
        self.orderHeaderDic = OrderedDict()
        self.orderHeaderList = []
        self.untradeHeaderDic = OrderedDict()
        self.untradeHeaderList = []
        self.accountHeaderDic = OrderedDict()
        self.accountHeaderList = []
        self.positionHeaderDic = OrderedDict()
        self.positionHeaderList = []
        self.contractHeaderDic = OrderedDict()
        self.contractHeaderList = []
        self.strategyParamHeaderDic = OrderedDict()
        self.strategyParamHeaderList = []
        self.strategyResultHeaderDic = OrderedDict()
        self.strategyResultHeaderList = []
        self.HeaderDic = OrderedDict()
        self.HeaderList = []

        self.sortingTick = True

        self.iniTableHeaderDic()

        self.connectCtpQuote()

        self.registerAllEvent()

    def setEventType(self):
        '''注册事件'''
        self.tickEventType = EVENT_TICK
        self.tradeEventType = EVENT_RSP_TRADE
        self.orderEventType = EVENT_RTN_ORDER
        self.untradeEventType = EVENT_UNTRADE
        self.accountEventType = EVENT_RSP_ACCOUNT
        self.positionEventType = EVENT_RSP_POSITION
        self.contractEventType = EVENT_RSP_INSTRUMENT

    def iniTableHeaderDic(self):
        '''设置表头有序字典'''
        # 设置行情表头有序字典
        self.tickHeaderDic['symbol'] = {'chinese': u'合约代码', 'cellType': BasicCell}
        self.tickHeaderDic['vtSymbol'] = {'chinese': u'名称', 'cellType': NameCell}
        self.tickHeaderDic['lastPrice'] = {'chinese': u'最新价', 'cellType': BasicCell}
        self.tickHeaderDic['preClosePrice'] = {'chinese': u'昨收盘价', 'cellType': BasicCell}
        self.tickHeaderDic['volume'] = {'chinese': u'成交量', 'cellType': BasicCell}
        self.tickHeaderDic['openInterest'] = {'chinese': u'持仓量', 'cellType': BasicCell}
        self.tickHeaderDic['openPrice'] = {'chinese': u'开盘价', 'cellType': BasicCell}
        self.tickHeaderDic['highPrice'] = {'chinese': u'最高价', 'cellType': BasicCell}
        self.tickHeaderDic['lowPrice'] = {'chinese': u'最低价', 'cellType': BasicCell}
        self.tickHeaderDic['bidPrice1'] = {'chinese': u'买一价', 'cellType': BidCell}
        self.tickHeaderDic['bidVolume1'] = {'chinese': u'买一量', 'cellType': BidCell}
        self.tickHeaderDic['askPrice1'] = {'chinese': u'卖一价', 'cellType': AskCell}
        self.tickHeaderDic['askVolume1'] = {'chinese': u'卖一量', 'cellType': AskCell}
        self.tickHeaderDic['time'] = {'chinese': u'时间', 'cellType': BasicCell}
        self.tickHeaderDic['gatewayName'] = {'chinese': u'接口', 'cellType': BasicCell}
        self.tickHeaderList = self.setTableHeader(self.twSelf, self.tickHeaderDic, True)
        # 设置成交表头有序字典
        self.tradeHeaderDic['tradeID'] = {'chinese': u'成交编号', 'cellType': BasicCell}
        self.tradeHeaderDic['orderID'] = {'chinese': u'委托编号', 'cellType': BasicCell}
        self.tradeHeaderDic['symbol'] = {'chinese': u'合约代码', 'cellType': BasicCell}
        self.tradeHeaderDic['vtSymbol'] = {'chinese': u'名称', 'cellType': NameCell}
        self.tradeHeaderDic['direction'] = {'chinese': u'方向', 'cellType': BasicCell}  # DirectionCell
        self.tradeHeaderDic['offset'] = {'chinese': u'开平', 'cellType': BasicCell}
        self.tradeHeaderDic['price'] = {'chinese': u'价格', 'cellType': BasicCell}
        self.tradeHeaderDic['volume'] = {'chinese': u'数量', 'cellType': BasicCell}
        self.tradeHeaderDic['tradeTime'] = {'chinese': u'成交时间', 'cellType': BasicCell}
        self.tradeHeaderDic['gatewayName'] = {'chinese': u'接口', 'cellType': BasicCell}
        self.tradeHHeaderList = self.setTableHeader(self.tblvwTrade, self.tradeHeaderDic, True)
        # 设置委托表头有序字典
        self.orderHeaderDic['orderID'] = {'chinese': u'委托编号', 'cellType': BasicCell}
        self.orderHeaderDic['symbol'] = {'chinese': u'合约代码', 'cellType': BasicCell}
        self.orderHeaderDic['vtSymbol'] = {'chinese': u'名称', 'cellType': NameCell}
        self.orderHeaderDic['direction'] = {'chinese': u'方向', 'cellType': BasicCell}  # DirectionCell
        self.orderHeaderDic['offset'] = {'chinese': u'开平', 'cellType': BasicCell}
        self.orderHeaderDic['price'] = {'chinese': u'价格', 'cellType': BasicCell}
        self.orderHeaderDic['totalVolume'] = {'chinese': u'委托数量', 'cellType': BasicCell}
        self.orderHeaderDic['tradedVolume'] = {'chinese': u'成交数量', 'cellType': BasicCell}
        self.orderHeaderDic['status'] = {'chinese': u'状态', 'cellType': BasicCell}
        self.orderHeaderDic['orderTime'] = {'chinese': u'委托时间', 'cellType': BasicCell}
        self.orderHeaderDic['cancelTime'] = {'chinese': u'撤销时间', 'cellType': BasicCell}
        self.orderHeaderDic['frontID'] = {'chinese': u'前置编号', 'cellType': BasicCell}
        self.orderHeaderDic['sessionID'] = {'chinese': u'会话编号', 'cellType': BasicCell}
        self.orderHHeaderList = self.setTableHeader(self.tblvwOrder, self.orderHeaderDic, True)
        # 设置未成交表头有序字典
        self.untradeHeaderDic['orderID'] = {'chinese': u'委托编号', 'cellType': BasicCell}
        self.untradeHeaderDic['symbol'] = {'chinese': u'合约代码', 'cellType': BasicCell}
        self.untradeHeaderDic['vtSymbol'] = {'chinese': u'名称', 'cellType': NameCell}
        self.untradeHeaderDic['direction'] = {'chinese': u'方向', 'cellType': BasicCell}  # DirectionCell
        self.untradeHeaderDic['offset'] = {'chinese': u'开平', 'cellType': BasicCell}
        self.untradeHeaderDic['price'] = {'chinese': u'价格', 'cellType': BasicCell}
        self.untradeHeaderDic['totalVolume'] = {'chinese': u'委托数量', 'cellType': BasicCell}
        self.untradeHeaderDic['tradedVolume'] = {'chinese': u'成交数量', 'cellType': BasicCell}
        self.untradeHeaderDic['status'] = {'chinese': u'状态', 'cellType': BasicCell}
        self.untradeHeaderDic['orderTime'] = {'chinese': u'委托时间', 'cellType': BasicCell}
        self.untradeHeaderDic['cancelTime'] = {'chinese': u'撤销时间', 'cellType': BasicCell}
        self.untradeHeaderDic['frontID'] = {'chinese': u'前置编号', 'cellType': BasicCell}
        self.untradeHeaderDic['sessionID'] = {'chinese': u'会话编号', 'cellType': BasicCell}
        self.untradeHeaderList = self.setTableHeader(self.tblvwUntrade, self.untradeHeaderDic, True)
        # 设置持仓表头有序字典
        self.positionHeaderDic['symbol'] = {'chinese': u'合约代码', 'cellType': BasicCell}
        self.positionHeaderDic['vtSymbol'] = {'chinese': u'名称', 'cellType': BasicCell}  # NameCell
        self.positionHeaderDic['direction'] = {'chinese': u'方向', 'cellType': BasicCell}  # DirectionCell
        self.positionHeaderDic['position'] = {'chinese': u'持仓量', 'cellType': BasicCell}
        self.positionHeaderDic['ydPosition'] = {'chinese': u'昨持仓', 'cellType': BasicCell}
        self.positionHeaderDic['frozen'] = {'chinese': u'冻结量', 'cellType': BasicCell}
        self.positionHeaderDic['price'] = {'chinese': u'价格', 'cellType': BasicCell}
        self.positionHeaderList = self.setTableHeader(self.tblvwHolding, self.positionHeaderDic, True)
        # 设置账户表头有序字典
        self.accountHeaderDic['accountID'] = {'chinese': u'账户', 'cellType': BasicCell}
        self.accountHeaderDic['preBalance'] = {'chinese': u'昨结', 'cellType': BasicCell}
        self.accountHeaderDic['balance'] = {'chinese': u'净值', 'cellType': BasicCell}
        self.accountHeaderDic['available'] = {'chinese': u'可用', 'cellType': BasicCell}
        self.accountHeaderDic['commission'] = {'chinese': u'手续费', 'cellType': BasicCell}
        self.accountHeaderDic['margin'] = {'chinese': u'保证金', 'cellType': BasicCell}
        self.accountHeaderDic['closeProfit'] = {'chinese': u'平仓盈亏', 'cellType': BasicCell}
        self.accountHeaderDic['positionProfit'] = {'chinese': u'持仓盈亏', 'cellType': BasicCell}
        # self.accountHeaderList = self.setTableHeader(self.tblvwAccount, self.accountHeaderDic, True)
        # 设置合约表头有序字典
        self.contractHeaderDic['symbol'] = {'chinese': u'合约代码', 'cellType': BasicCell}
        self.contractHeaderDic['exchange'] = {'chinese': u'交易所', 'cellType': BasicCell}
        self.contractHeaderDic['vtSymbol'] = {'chinese': u'vt系统代码', 'cellType': BasicCell}
        self.contractHeaderDic['name'] = {'chinese': u'名称', 'cellType': BasicCell}
        self.contractHeaderDic['productClass'] = {'chinese': u'合约类型', 'cellType': BasicCell}
        self.contractHeaderDic['size'] = {'chinese': u'大小', 'cellType': BasicCell}
        self.contractHeaderDic['priceTick'] = {'chinese': u'最小价格变动', 'cellType': BasicCell}
        self.contractHeaderDic['OpenRatioByMoney'] = {'chinese': '开仓费率', 'cellType': BasicCell}
        self.contractHeaderDic['OpenRatioByVolume'] = {'chinese': '开仓手续费', 'cellType': BasicCell}
        self.contractHeaderDic['CloseRatioByMoney'] = {'chinese': '平仓费率', 'cellType': BasicCell}
        self.contractHeaderDic['CloseRatioByVolume'] = {'chinese': '平仓手续费', 'cellType': BasicCell}
        self.contractHeaderDic['CloseTodayRatioByMoney'] = {'chinese': '平今费率', 'cellType': BasicCell}
        self.contractHeaderDic['CloseTodayRatioByVolume'] = {'chinese': '平今手续费', 'cellType': BasicCell}
        self.contractHeaderDic['LongMarginRatioByMoney'] = {'chinese': '多头保证金率', 'cellType': BasicCell}
        self.contractHeaderDic['ShortMarginRatioByMoney'] = {'chinese': '空头保证金率', 'cellType': BasicCell}
        self.contractHeaderList = self.setTableHeader(self.twContract, self.contractHeaderDic, True)

    def setTableHeader(self, table, headerDic, sorting=True):
        # 设置列表头
        labels = [d['chinese'] for d in headerDic.values()]
        table.setColumnCount(len(labels))
        headerList = headerDic.keys()

        table.setHorizontalHeaderLabels(labels)

        # 关闭左边的垂直表头
        # table.verticalHeader().setVisible(False)

        # 设为不可编辑
        table.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers)

        # 设为行交替颜色
        table.setAlternatingRowColors(True)

        # 设置允许排序
        table.setSortingEnabled(sorting)

        return headerList

    def registerAllEvent(self):

        self.registerTickEvent()

    def registerTickEvent(self):
        """注册GUI更新相关的事件监听"""
        self.signalTick.connect(self.updateTickEvent)
        self.quoteEventEngine.register(self.tickEventType, self.signalTick.emit)

    def updateTickEvent(self, event):
        """收到事件更新"""
        data = event.dict_['data']

        self.updateTickData(data)

    def updateTickData(self, data):
        """将数据更新到表格中"""
        table = self.twSelf

        # 如果允许了排序功能，则插入数据前必须关闭，否则插入新的数据会变乱
        if self.sortingTick:
            table.setSortingEnabled(False)

        # 如果设置了tickKey，则采用存量更新模式
        if self.tickKey:
            key = data.__getattribute__(self.tickKey)

            # 如果键在数据字典中不存在，则先插入新的一行，并创建对应单元格
            if key not in self.tickDict.keys():
                table.insertRow(0)
                d = {}
                for n, header in enumerate(self.tickHeaderList):
                    content = safe_unicode(data.__getattribute__(header))
                    cellType = self.tickHeaderDic[header]['cellType']
                    cell = cellType(content, None)  # self.mainEngine

                    # if table.font:
                    #     cell.setFont(self.font)  # 如果设置了特殊字体，则进行单元格设置

                    cell.data = data

                    table.setItem(0, n, cell)
                    d[header] = cell
                self.tickDict[key] = d
            # 否则如果已经存在，则直接更新相关单元格
            else:
                d = self.tickDict[key]
                for header in self.tickHeaderList:
                    content = safe_unicode(data.__getattribute__(header))
                    cell = d[header]
                    cell.setContent(content)
                    cell.data = data

        # 调整列宽
        table.horizontalHeader().resizeSections(QtWidgets.QHeaderView.ResizeToContents)
        # 重新打开排序
        if self.sortingTick:
            table.setSortingEnabled(True)

    def connectCtpQuote(self):
        """连接CTP行情接口"""
        self.quoteEngine.connect('CTPQuote')

    def closeEvent(self, event):
        """关闭事件"""
        reply = QtWidgets.QMessageBox.question(self, '退出',
                                               '确认退出?', QtWidgets.QMessageBox.Yes |
                                               QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)

        if reply == QtWidgets.QMessageBox.Yes:
            # for widget in self.widgetDict.values():
            #     widget.close()
            self.saveWindowSettings()

            if self.mainEngine:
                self.mainEngine.exit()
            if self.quoteEngine:
                self.quoteEngine.exit()
            event.accept()
        else:
            event.ignore()

    def saveWindowSettings(self):
        pass


# ----------------------------------------------------------------------
def main():
    """主程序入口"""
    # 重载sys模块，设置默认字符串编码方式为utf8
    importlib.reload(sys)
    # sys.setdefaultencoding('utf8')

    # 设置Windows底部任务栏图标
    if 'Windows' in platform.uname():
        ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('BoxiQuant')

    # 初始化Qt应用对象
    app = QtWidgets.QApplication(sys.argv)
    app.setWindowIcon(QtGui.QIcon('vnpy.ico'))
    # app.setFont(BASIC_FONT)

    # 设置Qt的皮肤
    try:
        f = open("VT_setting.json")
        setting = json.load(f)
        print(setting)
        if setting['darkStyle']:
            import qdarkstyle
            app.setStyleSheet(qdarkstyle.load_stylesheet(pyside=False))
    except:
        pass

    # 初始化主引擎和主窗口对象
    # mainEngine = MainEngine()
    # quoteEngine = QuoteEngine()
    # time.sleep(2)
    mainWindow = UiIndicator()
    mainWindow.show()
    # mainWindow.showMaximized()

    # 在主线程中启动Qt事件循环
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
